/*
 * 								SYMBIOS
 *
 * TrackFaces.cpp
 *
 *  Created on: Jun 1, 2009
 *      Author: andrei
 */

#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include "capture.h"
#include "gesture_rec.h"
#include "facedet.h"
#include "camshift_wrapper.h"
#include "Interface.h"
#include "parameters.h"
#include "Selection.h"

//// Global variables
IplImage* pVideoFrameCopy = 0;			//Image courante
bool handState = false;			//true : main fermé, false : main ouverte
float handX, handY;
//// Function definitions
int initAll();							// Allocation image, fenetre...
void exitProgram(int code);				// Libération mémoire
void captureVideoFrame();				// Actualise pVideoFrame

int TrackFaces()
{
// INITIALISATION
	CvRect * pFaceRect = 0;
	if( !initAll() ) exitProgram(-1);

//CREATION HISTOGRAMME CHAIR
	while( 1 )
	{
		captureVideoFrame();			// acquisition dans pVideoFrame
		pFaceRect = detectFace(pVideoFrameCopy);
		if( (char)27==cvWaitKey(10) ) break;				// on sort si ESC
		if(pFaceRect) break;								// on sort si le visage est detecté
	}

//INITIALISATION DU TRACKING
	startTracking(pVideoFrameCopy, pFaceRect);

// BOUCLE PRINCIPALE DU TRACKING
	while( 1 )
	{
		CvBox2D handBox;							//rectangle du tracking = repere la main
		IplImage* hand;				//la main en NoirBlanc et son contour

		//ACQUISITION
		captureVideoFrame();
		// => RESULTAT : l'image acquise est dans pVideoFrameCopy

		//EXTRACTION DE CHAIR
		hand = cvCloneImage( extractFlesh(pVideoFrameCopy) );	//recuperer la main en noir et blanc a partir de limage acquise
		// => RESULTAT : la main en Noir et Blanc
		cvShowImage("test1",hand);
		//TRACK FACE

		CvPoint2D32f pointf;
		handBox = track(pVideoFrameCopy);
		pointf = handBox.center;
		//TRACE DU RECTANGLE MINIMAL
		int size=0;
		size = traceMinRect(hand, pVideoFrameCopy,pointf);

		//RECONNAISSANCE SELECTION ADVANCED
		int result=recognizeSelection(size, pointf);
		//AFFICHAGE
		//cvRectangle(pVideoFrameCopy, cvPoint(handX-handBox.size.width/2,handY-handBox.size.width/2), cvPoint(handX+handBox.size.width/2,handY+handBox.size.width/2), CV_RGB(255,55,34), 1, 8,0);
		affichage(pVideoFrameCopy,handBox.center,result);

		if( (char)27==cvWaitKey(10) ) break;
	}

	exitProgram(0);
	return 0;
}


//////////////////////////////////
// initAll()
//

int initAll()
{
	if( !initCapture() ) return 0;
	if( !initFaceDet(SYMB_HAAR))
		return 0;

	//INIT AFFICHAGE
	initInterface();

	//INITIALISATION TRACKING
	captureVideoFrame();
	if( !createTracker(pVideoFrameCopy) ) return 0;

	//INIT RECOGNITION
	initRecognition();


	//CAMSHIFT PARAM
	setVmin(60);
	setSmin(50);

	return 1;
}


//////////////////////////////////
// exitProgram()
//
void exitProgram(int code)
{

	//RELEASE IMAGE
	cvReleaseImage( &pVideoFrameCopy );

	//CLOSE RESOURCES
	closeInterface();
	closeCapture();
	closeFaceDet();
	closeGestureRec();
	releaseTracker();

	exit(code);
}


//////////////////////////////////
// captureVideoFrame()
//
void captureVideoFrame()
{
	// Capture the next frame
	IplImage  * pVideoFrame = nextVideoFrame();
	if( !pVideoFrame ) exitProgram(-1);

	// Copy it to the display image, inverting it if needed
	if( !pVideoFrameCopy )
		pVideoFrameCopy = cvCreateImage( cvGetSize(pVideoFrame), 8, 3 );
	cvCopy( pVideoFrame, pVideoFrameCopy, 0 );
	pVideoFrameCopy->origin = pVideoFrame->origin;

	if( 1 == pVideoFrameCopy->origin ) // 1 means the image is inverted
	{
		cvFlip( pVideoFrameCopy, 0, 0 );
		pVideoFrameCopy->origin = 0;
	}
}
